<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{ position: relative; }
        .container .item{ position: absolute; width: 50px; height: 50px; text-align: center; line-height: 50px; background-color: cornflowerblue; color: #fff; box-sizing: border-box; border: 1px solid #fff;}
        /* .bottom{ position: absolute; top: 420px; left: 5px; right: 0; } */
        button{ appearance: none; border: none; outline: none; padding: 5px 12px; border-radius: 4px;  }
        button:active{ background-color: #eee; }
        button.orange{ background-color: darkorange; color: #fff; }
        button.orange:active{ background-color: orange; }
        .bottom button{ display: block; width: 400px;   margin-bottom: 5px; }
    </style>
</head>
<body>

    <div class="bottom">
        <button id="sort" type="button" class="orange">排序</button>
        <button id="shuffle" type="button">重排</button>
    </div>
    
    <div class="container">

    </div>

    

    <script src="../js/jquery-3.4.1.js"></script>
    <script>
        
        Array.prototype.shuffle = function() {
            var input = this;

            for (var i = input.length-1; i >=0; i--) {

                var randomIndex = Math.floor(Math.random()*(i+1));
                var itemAtIndex = input[randomIndex];

                input[randomIndex] = input[i];
                input[i] = itemAtIndex;
            }
            return input;
        }

        Array.prototype.sortNum = function(){
            var input = this;
            var start = 0;
            /*
                start   at  j   m   move    result
                0       8   0   -   -       [8, 3, 1, 2, 5]
                1       3   0   8   0-1     [3, 8, 1, 2, 5]
                2       1   0   3   0-2     [1, 3, 8, 2, 5]
                3       2   0   1   -       [1, 3, 8, 2, 5]
                            1   3   1-3     [1, 2, 3, 8, 5]
                4       5   0   1   -
                            1   2   -
                            2   3   -
                            3   8   3-4     [1, 2, 3, 5, 8]
            */
            var c = 0;
            while(start < input.length){
                var at = input[start];
                for(var j = 0; j < start; j++){
                    var m = input[j];
                    if(at < m){
                        move(j, start);
                        input[j] = at;
                        break;
                    }
                    c++;
                }
                start++;
            }
            console.log('共排序了' + c + '次');
            /*
                i   at  result
                3   2   [8, 3, 1, 2, 2]
                2   1   [8, 3, 1, 1, 2]
                1   3   [8, 3, 3, 1, 2]
            */
            function move(from, to){
                for(var i = to - 1; i >= from; i--){
                    var at = input[i];
                    input[i + 1] = at;
                }
            }
            return input;
        }

        var $c = $('.container');
        var count = 8; // 每行/每列的数量
        // 1. 准备数据
        var digits = [];
        for(var i = 1;i <= count * count; i++){
            digits.push(i);
        }
        // 2. 洗牌
        digits.shuffle();
        // 3. 渲染
        render(digits, true)
        // 排序
        $('#sort').click(function(){
            render(digits.sortNum(), true);
        })
        // 重新洗牌
        $('#shuffle').click(function(){
            render(digits.shuffle(), true);
        })

        function render(digits, ani){
            var cache = {};
            digits.forEach(function(digit, index){
                var $item = $c.find('.item').filter(function(){
                    return $(this).text() == digit;
                });
                if(!$item.length){
                    $item = $('<div class="item"></div>').text(digit).appendTo($c);
                }
                cache[digit] = {
                    item: $item,
                    position: position(index)
                }
            })
            Object.keys(cache).forEach(function(key, index){
                var digit = key,
                    $item = cache[key].item,
                    pos = cache[key].position;
                
                $item.animate({
                    left: pos.col + 'px',
                    top: pos.row + 'px'
                }, ani ? 500 : 0);
            })
        }

        function position(digit){
            var row = parseInt(digit / count) * 50;
            var col = parseInt(digit % count) * 50;
            return {row: row, col: col};
        }
    </script>

</body>
</html>